//
//  NSObjectExtensions.swift
//  EZSwiftExtensions
//
//  Created by yiwanjun on 16/07/15.
//  Copyright (c) 2015 Goktug Yilmaz. All rights reserved.
//

#if os(iOS) || os(tvOS)
import Foundation

private var weakProxyKey = 0

public extension NSObject {
    
    /// 获取代理对象，通常用于解除循环引用
    var weakProxyObject: WeakProxySwift {
        get {
            if weakProxy == nil {
                weakProxy = WeakProxySwift(target: self)
            }
            return weakProxy!
        }
    }
    
    private var weakProxy: WeakProxySwift? {
        set {
            objc_setAssociatedObject(self, &weakProxyKey, newValue, .OBJC_ASSOCIATION_RETAIN)
        }
        get {
            objc_getAssociatedObject(self, &weakProxyKey) as? WeakProxySwift
        }
    }
}

public class WeakProxySwift: NSObject /* & NSProxy */ {
    
    // 只有继承NSObject类的子类才有消息转发机制，swift基类如果不继承基类，将是静态类，不存在消息动态转发
    public weak var target: NSObject?
    
    public static func  proxyWithTarget(target:NSObject) -> WeakProxySwift{
        return WeakProxySwift.init(target: target)
    }
    
    public convenience init(target: NSObject){
        self.init()
        self.target = target
    }
    //  核心代码
    public override func forwardingTarget(for aSelector: Selector!) -> Any? {
        return target
    }
    
    
    // NSObject 一些方法复写
    
    public override func isEqual(_ object: Any?) -> Bool {
        return target?.isEqual(object) ?? false
    }
    
    public override var hash: Int  {
        return target?.hash ?? -1
    }
    
    public override var superclass: AnyClass? {
        return target?.superclass ?? nil
    }
    
    //    override func `self`() -> Self{
    //        return target?.self()
    //    }
    
    
    public override func isProxy() -> Bool {
        return true
    }
    
    public override func isKind(of aClass: AnyClass) -> Bool {
        return target?.isKind(of: aClass) ?? false
    }
    
    public override func isMember(of aClass: AnyClass) -> Bool {
        return target?.isMember(of: aClass) ?? false
    }
    
    public override func conforms(to aProtocol: Protocol) -> Bool {
        return  target?.conforms(to: aProtocol) ?? false
    }
    
    public override func responds(to aSelector: Selector!) -> Bool {
        return target?.responds(to: aSelector) ?? false
    }
    
    public override var description: String {
        return target?.description ?? "nil"
    }
    
    public override var debugDescription: String {
        return target?.debugDescription ?? "nil"
    }
    
    deinit {
        debugPrint("Proxy dealloc")
    }
    
}

public extension NSObject {
    
    /// 类名,不带模块名，如： ViewController
    var className: String {
        return type(of: self).className
    }
    
    /// 类名，带模块名，如： Example.ViewController
    var fullClassName: String? {
        self.description.components(separatedBy: ":").first?.components(separatedBy: "<").last
    }
    
    /// 类名，不带模块名，如：ViewController
    static var className: String {
        return String(describing: self)
    }
    
    /// 交换某个类的方法
    /// - Parameters:
    ///   - cls: 类类型
    ///   - originalSelector: 原始的Selector
    ///   - swizzleSelector: 新的Selector
    class func exchange(_ cls: AnyClass, originalSelector: Selector, swizzleSelector: Selector) {
        // 创建方法
       
        guard let ori_method = class_getInstanceMethod(cls, originalSelector),
              let swi_method = class_getInstanceMethod(cls, swizzleSelector) else {
            return
        }
        
        let didAdd = class_addMethod(cls, originalSelector, method_getImplementation(swi_method), method_getTypeEncoding(swi_method))
        
        if didAdd == true {
            class_replaceMethod(cls, swizzleSelector, method_getImplementation(ori_method), method_getTypeEncoding(ori_method))
        }else {
            method_exchangeImplementations(ori_method,swi_method)
        }
    }
}

#endif
